/*
 * SDLApp.cpp
 *
 *  Created on: 12 jan 2010
 *      Author: Andreas
 */

#include "SDLApp.h"
#include <SDL/SDL_opengl.h>
#include <iostream>
#include "graphics/Sprite.h"
#include "graphics/ScreenManager.h"

using namespace std;

SDLApp::SDLApp(int w, int h, int bpp)
: scrw(w), scrh(h), scrbpp(bpp) {
	lasttime=0;
	//Initialize SDL
	SDL_Init( SDL_INIT_EVERYTHING );


	SDL_Rect res[3];
	res[0].w = 1920;
	res[0].h = 1080;
	res[1].w = 1680;
	res[1].h = 1050;
	res[2].w = 1280;
	res[2].h = 1024;

	screen = NULL;

	//Create Window and try different resolutions
	int i=0;
	for (; i<3; i++) {
		scrw = res[i].w;
		scrh = res[i].h;
		screen = SDL_SetVideoMode( scrw, scrh, scrbpp, SDL_OPENGL |SDL_GL_DOUBLEBUFFER|SDL_FULLSCREEN| SDL_HWSURFACE );
		if (screen) {
			cout << "Setting up screen in fullscreen mode " << scrw << " x " << scrh << "." << endl;
			ScreenManager::setupScreen(scrw, scrh);
			break;
		}
	}
	if (i==3) {
		cout << "No screen resolution worked. Quitting..." << endl;
		exit(1);
	}

	//Initialize OpenGL
	init_GL();

	quit = false;
}

bool SDLApp::init_GL()
{
    //Set projection
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    glOrtho( 0, scrw, scrh, 0, -1, 1 );

    //Initialize modelview matrix
    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();

    //If there was any errors
    if( glGetError() != GL_NO_ERROR )
    {
        return false;
    }

    //Set clear color
    glClearColor( 0, 0, 0, 0 );
    glShadeModel( GL_SMOOTH );
    glClearDepth( 0.0f );
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable( GL_DEPTH_TEST );
    glDepthFunc( GL_ALWAYS );
    glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );

    glDisable(GL_LIGHTING);

    glEnable(GL_BLEND);
    glEnable(GL_TEXTURE_2D);

    //If everything initialized
    SetVSync(false);
    return true;
}

SDLApp::~SDLApp() {
}

void SDLApp::start() {
	SDL_Event event;

	fpstime = 0;
	frames = 0;

	init();
	while(!quit) {
		while (SDL_PollEvent(&event)) {
			handleEvents(&event);
		}

		handleInput();
		int elapsed= (SDL_GetTicks()-lasttime);

		frames++;
		fpstime += elapsed;
		if (fpstime >= 1000) {
			fps = frames;
			fpstime -= 1000;
			frames = 0;
		}

		lasttime=SDL_GetTicks();

		if (status != STATE_MINIMIZED) {
			update(elapsed);
			draw();
		}
	}
}

void SDLApp::handleEvents(SDL_Event *event) {
	if (event->type == SDL_QUIT) {
		quit = true;
	}
	if (( event->type == SDL_KEYDOWN ) && ( event->key.keysym.sym == SDLK_ESCAPE ) ) {
		if (status == STATE_MENU) {
			quit = true;
		}
	}
}

void SDLApp::clearScreen() {
	SDL_Rect r;
	r.x = 0;
	r.y = 0;
	r.w = scrw;
	r.h = scrh;
	SDL_FillRect(screen, &r, SDL_MapRGB(screen->format, 0, 0, 0));
}

void SDLApp::setStatus(GameStatus s) {
	status = s;
}

void SDLApp::setQuit(bool q) {
	quit = q;
}

void SDLApp::SetVSync(bool sync)
{
	typedef bool (APIENTRY *PFNWGLSWAPINTERVALFARPROC)(int);

	PFNWGLSWAPINTERVALFARPROC wglSwapIntervalEXT = 0;

	wglSwapIntervalEXT = (PFNWGLSWAPINTERVALFARPROC)wglGetProcAddress("wglSwapIntervalEXT");

	if( wglSwapIntervalEXT )
		wglSwapIntervalEXT(sync);
}

